/*
 * Logger.cpp
 *
 *  Created on: Oct 9, 2014
 *      Authors: Avihay Avitan & Stefan Farcas
 */

#include "Logger.h"

#define ANSI_COLOR_BLUE     "\x1b[34;1m"
#define ANSI_COLOR_MAGENTA  "\x1b[35;1m"
#define ANSI_COLOR_RED      "\x1b[31;1m"
#define ANSI_COLOR_GREEN   "\x1b[32;1m"
#define ANSI_COLOR_CYAN   	"\x1b[36;1m"
#define ANSI_COLOR_RESET   	"\x1B[0m"

namespace LoggerNameSpace {

/**
 * construct a Logger object - opens\create a file named by filename.
 * note: only if the logger is for the main GSPASS.log than the progress status publisher is initiated too.
 */
Logger::Logger (string filename)
{
	if (CoreSettings::getInstance().getGSLogFilePath().compare(filename) == 0 && CoreSettings::getInstance().isPublishStatus())
		publisher = new ProgressStatusPublisher();
	logfile = fopen(filename.c_str(),"a+");
	isCR=false;
	CRfirst = false;
	if (logfile == NULL)
		std::cout << "Error loading file " << filename << std::endl ;
}

Logger::~Logger ()
{
	fclose(logfile);
	// TODO Auto-generated destructor stub
}

/**
 * log the ProgressStatus info
 * status - the status to be logged
 */
void Logger::logInfo (ProgressStatus status)
{
	log (status, LoggingColor::BLACK );
}

/**
 * log the ProgressStatus info with the required color
 * status - the status to be logged
 * color - the required color
 */
void Logger::logInfo (ProgressStatus status, LoggingColor color)
{
	log (status, color );
}

/**
 * log the ProgressStatus info with carriage return character
 * status - the status to be logged
 * color - the required color
 * isFirst - whether the line is the first line or not (when false, it will override the prev line with the new one)
 */
void Logger::logInfoCR(ProgressStatus status, LoggingColor color, bool isFirst)
{
	isCR=true;
	CRfirst=isFirst;
	log (status , color);
}

/**
 * log the ProgressStatus info with ERROR type
 * status - the status to be logged
 */
void Logger::logError (ProgressStatus status)
{
	log (status, LoggingColor::RED );
}

/**
 * log the ProgressStatus info with WARNING type
 * status - the status to be logged
 */
void Logger::logWarning (ProgressStatus status)
{
	log (status, LoggingColor::GREEN );
}

/**
 * will publish the status to external module if enabled
 */
void Logger::publish(ProgressStatus status)
{
    if(CoreSettings::getInstance().isPublishStatus() && status.getIsToPublish())
    {
    	publisher->publishProgressStatus(status);
    }
}


void Logger::log (ProgressStatus status, LoggingColor color)
{

	string times = status.getTimeStampString();
	string consoleLine=times;
	string content = "";

	switch (status.getProgressStatusType())
	{
		case ProgressStatusType::ERR :
		{
			content.append("ERR");
			break;
		}
		case ProgressStatusType::WRN :
		{
			content.append("WRN");
			break;
		}
		default :
		{
			content.append("INF");
			break;
		}
	}
	content.append(": [" + status.getClass() + "] ");
	content.append(status.getFunction() + " - ");
	content.append(status.getContent());
	writeLineTofile (times + content);

	publish(status);

    if(CoreSettings::getInstance().isColorTextSupported())
    {
    	consoleLine.append(fillTextWithColor(content, color));
    }
    else
    	consoleLine += content;

    if (status.isFromConsole())
    {
    	if (isCR)
    	{
    		if (CoreSettings::getInstance().isColorTextSupported())
    		{
    			if (!CRfirst)
    				consoleLine = "\033[1A"+consoleLine;
    		}
    		else
    		{
    		    isCR = false;
    		    return;
    		}
    	}

        writeLineToTerminal(consoleLine);
    }

    isCR = false;
}



void Logger::writeLineToTerminal (string text)
{
	fprintf(stdout,text.c_str());
	fprintf(stdout,"\n");
	fflush(stdout);
}

void Logger::writeLineTofile (string text)
{
	fprintf(logfile,text.c_str());
	fprintf(logfile,"\n");
	fflush(logfile);
}

string Logger::fillTextWithColor(string text, LoggingColor color)
{
	string textWColor="";

	switch (color)
	{
		case 1:
		{
			textWColor.append(ANSI_COLOR_BLUE);
			textWColor.append(text);
			textWColor.append(ANSI_COLOR_RESET);
			break;
		}
		case 2:
		{
			textWColor.append(ANSI_COLOR_MAGENTA);
			textWColor.append(text);
			textWColor.append(ANSI_COLOR_RESET);
			break;
		}
		case 3:
		{
			textWColor.append(ANSI_COLOR_RED);
			textWColor.append(text);
			textWColor.append(ANSI_COLOR_RESET);
			break;
		}
		case 4:
		{
			textWColor.append(ANSI_COLOR_GREEN);
			textWColor.append(text);
			textWColor.append(ANSI_COLOR_RESET);
			break;
		}
		case 5:
		{
			textWColor.append(ANSI_COLOR_CYAN);
			textWColor.append(text);
			textWColor.append(ANSI_COLOR_RESET);
			break;
		}
		default:
		{
			textWColor.append(text);
			break;
		}
	}

	return textWColor;
}


} /* namespace LoggerNameSpace */
